package com.xia.demo;

//此处T可以随便写为任意标识，常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时，必须指定T的具体类型
public class Generic<T>{
    //key这个成员变量的类型为T,T的类型由外部指定
    private T key;

    public T getKey() {
        return key;
    }

    public Generic(T key) {
        this.key = key;
    }

    //泛型的类型参数只能是类类型，不能是简单类型。 此处’？’是类型实参，而不是类型形参
    // 只使用Object类中的功能。那么可以用 ? 通配符来表未知类型
    public static void showKeyValue1(Generic<?> obj){
        System.out.println(obj.getKey());
    }
    public static void showKeyValue2(Generic<Number> obj){
        System.out.println(obj.getKey());
    }
    public static void showKeyValue3(Generic<Integer> obj){
        System.out.println(obj.getKey());
    }


    /**
     * 泛型方法的基本介绍
     * @param tClass 传入的泛型实参
     * @return T 返回值为T类型
     * 说明：
     *     1）public 与 返回值中间<T>非常重要，可以理解为声明此方法为泛型方法。
     *     2）只有声明了<T>的方法才是泛型方法，泛型类中的使用了泛型的成员方法并不是泛型方法。
     *     3）<T>表明该方法将使用泛型类型T，此时才可以在方法中使用泛型类型T。
     *     4）与泛型类的定义一样，此处T可以随便写为任意标识，常见的如T、E、K、V等形式的参数常用于表示泛型。
     */
    public  <E> E genericMethod(Class<E> tClass)throws InstantiationException ,
            IllegalAccessException{
        E instance = tClass.newInstance();
        return instance;
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Generic<Integer> gInteger = new Generic<Integer>(123);
//        Generic<Number> gNumber = new Generic<Number>(456);
//        // 报错 此处’？’是类型实参，而不是类型形参
//        showKeyValue3(gInteger);
        Test1 test1 = gInteger.genericMethod(Test1.class);
        test1.test1();
    }

}